package callcenter.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import callcenter.dao.AgentDao;


/**
 * Session Bean implementation class AgentBean
 */
@Stateless
public class AgentService  {

	@EJB
	private AgentDao agentDao;
	@EJB
	private PeerEao peerEao;
	@EJB
	private PeerStateEao peerStateEao;
	@EJB
	private CampaignEao campaignEao;
	@EJB
	private QueueEao queueEao;
	@EJB
	private SessionTypeEao sessionTypeEao;
	@EJB
	private SessionEao sessionEao;
	@EJB
	private ManagerBean managerBean;
	@EJB
	private Conversion conv;
	
	private final String SESSION_TYPE_SESSION = "session";
	private final String SESSION_TYPE_READY = "ready";
	private final String SESSION_TYPE_PAUSE = "pause";
	private final String SESSION_TYPE_BREAK = "break";
	private final String SESSION_TYPE_LOGOUT = "logout";
	private final String SESSION_TYPE_BREAK_WITH_CALL = "breakwithcall";
	private final String SESSION_TYPE_PAUSE_WITH_CALL = "pausewithcall";
	private final String SESSION_TYPE_LOGOUT_WITH_CALL = "logoutwithcall";
	private final String SESSION_TYPE_PAUSE_WITH_CLOSE = "pausewithclose";


	@Override
	public AgentDto findAgentWithPeer(String username, Integer userId) throws CustomExcepcion {
		try {
			// SE BUSCA AGENT
			Agent agent = agentEao.findAgent(userId, username);
			// SE BUSCA PEER
			Peer peer = peerEao.findPeer(agent.getId());
			// SE VERIFICA ESTADO DEL PEER
			String status = managerBean.checkPeerStatus(peer.getName(), peer
					.getServer().getIp(), peer.getServer().getAmiUser(), peer
					.getServer().getAmiPassword(), peer.getServer()
					.getAmiPort());
			status = status.replace("Status: ", "").trim();
			Integer statusCode = Integer.parseInt(status);
			if (statusCode == 4 || statusCode == -1) {
				
				agent.setPeer(peer);
				AgentDto ad = conv.fromAgentWithPeer(agent);
				return ad;
			} else {
				throw new CustomExcepcion(
						"El c�digo de estado de la extensi�n es:" + statusCode);
			}
		} catch (NumberFormatException e) {
			throw new CustomExcepcion(
					"Ocurri� un error al convertir el estado del peer de caracter a n�mero");
		} catch (Exception e) {
			throw new CustomExcepcion(e.getMessage());
		}
	}
	
	@Override
	public AgentDto doLogin(String username, Integer userId,String ipHost) throws CustomExcepcion {
		try {
			// SE BUSCA AGENT
			Agent agent = agentEao.findAgent(userId,username);
			// SE BUSCA PEER
			//Peer peer = peerEao.findPeer(agent.getId());
			// SE VERIFICA ESTADO DEL PEER
			/*String status = managerBean.checkPeerStatus(peer.getName(), peer
					.getServer().getIp(), peer.getServer().getAmiUser(), peer
					.getServer().getAmiPassword(), peer.getServer()
					.getAmiPort());
			status = status.replace("Status: ", "").trim();
			Integer statusCode = Integer.parseInt(status);
			if (statusCode == 4 || statusCode == -1) {
				
				agent.setPeer(peer);
				AgentDto ad = conv.fromAgentWithPeer(agent);
				return ad;
			} else {
				throw new CustomExcepcion(
						"El codigo de estado de la extension es:" + statusCode);
			}*/
			
			List<Campaign> campaigns = campaignEao.findByAgent(agent.getId());
			//System.out.println("la cantidad de campaigns es:"+campaigns.size());
			if (campaigns.size()>0) {
				Campaign campaign1 = campaigns.get(0);
				Server server = campaign1.getServer();
				//BUSCA EL PEER
				//String peer = managerBean.findPeer(ipHost, server.getIp(), server.getAmiUser(), server.getAmiPassword(), server.getAmiPort());
				
				PeerState peerState = peerStateEao.findByHost(ipHost,server.getId());
				//PeerStateDto peerStateDto = conv.fromPeerState(peerState);
				
				if (peerState.getState().equals("Registered")) {
					//SE INICIALIZAN OBJETOS
					SessionType sessionTypeSession = sessionTypeEao
							.findType(SESSION_TYPE_SESSION);
					SessionType sessionTypeReady = sessionTypeEao
							.findType(SESSION_TYPE_READY);
					SessionType sessionTypePause = sessionTypeEao
							.findType(SESSION_TYPE_PAUSE);
					
					List<Session> sessions = new ArrayList<Session>();
					
					for (Campaign campaign : campaigns) {
						
						
						// VERIFICA SESIONES ABIERTAS
						Session openSession = sessionEao.findOpenSession(
								campaign.getId(), agent.getId(), sessionTypeSession.getId());
						if (openSession == null) {
							// SE CREA NUEVA SESSION
							openSession = new Session();
							openSession.setAgent(agent);
							openSession.setCampaign(campaign);
							openSession.setHost(ipHost);
							openSession.setPeer(peerState.getName());
							openSession.setSessionType(sessionTypeSession);
							openSession.setStartedAt(new Date());
							openSession = sessionEao.createSession(openSession);
							sessions.add(openSession);
							// SE CREA NUEVO ESTADO
							Session openState = new Session();
							openState.setAgent(agent);
							openState.setCampaign(campaign);
							openState.setHost(ipHost);
							openState.setPeer(peerState.getName());
							openState.setSession(openSession);
							if (agent.getAutoready()) {
								openState.setSessionType(sessionTypeReady);
							} else {
								openState.setSessionType(sessionTypePause);
							}
							openState.setStartedAt(new Date());
							openState = sessionEao.createSession(openState);
							sessions.add(openState);

						} else {
							// SE VERIFICAN ESTADOS ABIERTOS
							Session openState = sessionEao.findOpenStates(openSession
									.getId());
							if (openState == null) {
								// SE CREA NUEVO ESTADO
								openState = new Session();
								openState.setAgent(agent);
								openState.setCampaign(campaign);
								openState.setHost(ipHost);
								openState.setPeer(peerState.getName());
								openState.setSession(openSession);
								if (agent.getAutoready()) {
									openState.setSessionType(sessionTypeReady);
								} else {
									openState.setSessionType(sessionTypePause);
								}
								openState.setStartedAt(new Date());
								openState = sessionEao.createSession(openState);
							}
							sessions.add(openSession);
							sessions.add(openState);
						}

						// VERIFICA COLAS
						System.out.println("antes de finqueues");
						List<String> queues = queueEao.findQueues(campaign.getId());
						System.out.println("antes de addmanyqueues");
						String respuesta = managerBean.addManyQueues(queues, peerState.getName(), campaign.getServer().getIp(), campaign.getServer()
								.getAmiUser(), campaign.getServer().getAmiPassword(), campaign
								.getServer().getAmiPort());
						System.out.println("despues de addmanyqueues");
						if (respuesta.equals("OK")) {
							if (!agent.getAutoready()) {
								respuesta = managerBean.pauseManyQueues(queues, peerState.getName()
										, campaign.getServer().getIp(), campaign
										.getServer().getAmiUser(), campaign.getServer()
										.getAmiPassword(), campaign.getServer()
										.getAmiPort());
								if (!respuesta.equals("OK")) {
									throw new CustomExcepcion(
											"La respuesta del Manager es diferente de OK.");
								}
							}
						} else {
							throw new CustomExcepcion(
									"La respuesta del Manager es diferente de OK.");
						}
					}
					
					//SE CONVIERTE EN DTO
					AgentDto agentDto = conv.fromAgent(agent);
					List<SessionDto> sessionsDto = new ArrayList<SessionDto>();
					
					for (Session session : sessions) {
					SessionDto sessionDto = conv.fromSession(session);
					sessionsDto.add(sessionDto);
					}
					
					agentDto.setSessions(sessionsDto);
					PeerDto peerDto = new PeerDto();
					peerDto.setName(peerState.getName());
					agentDto.setPeer(peerDto);
					
					return agentDto;
				}else{
					throw new CustomExcepcion(
							"El codigo de estado de la extension es :" + peerState.getState());	
				}
				
				
				
			}else{
				throw new CustomExcepcion(
						"El agente no tiene ninguna campa�a asignada.");
			}
			
			
			
		} /*catch (NumberFormatException e) {
			throw new CustomExcepcion(
					"Ocurrio un error al convertir el estado del peer de caracter a numero");
		}*/ catch (Exception e) {
			throw new CustomExcepcion(e.getMessage());
		}
	}

	
	
	@Override
	public AgentDto changeState(Integer agentId, String peer, String host,
			String stateCode) throws CustomExcepcion {
		try {
			
			System.out.println("ingreso a changeState en el ejb");
			System.out.println("stateCode:"+stateCode);
			List<Campaign> campaigns = campaignEao.findByAgent(agentId);
			Agent agent = agentEao.findAgentById(agentId);
			//Peer peer = peerEao.findPeer(agentId);
			SessionType sessionTypeSelected = sessionTypeEao
					.findType(stateCode);
			SessionType sessionTypeSession = sessionTypeEao
					.findType(SESSION_TYPE_SESSION);

			List<Session> sessions = new ArrayList<Session>();
			
			System.out.println("cantidad de camapañas " + campaigns.size());

			for (Campaign campaign : campaigns) {

				// VERIFICA SESIONES ABIERTAS
				System.out.println("antes del error");
				Session openSession = sessionEao.findOpenSession(
						campaign.getId(), agentId, sessionTypeSession.getId());
				System.out.println("despues del error");
				if (openSession != null) {
					sessions.add(openSession);
					// SE VERIFICAN ESTADOS ABIERTOS
					Session oldState = sessionEao.findOpenStates(openSession
							.getId());
					if (oldState != null) {
						// SE ACTUALIZA ESTADO ANTIGUO
						System.out.println("antes de actualizar estado antiguo");
						oldState.setEndedAt(new Date());
						sessionEao.createSession(oldState);
						System.out.println("despues de actualizar estado antiguo");
						
					} else {
						throw new CustomExcepcion("No existe estado activo.");
					}
				} else {
					throw new CustomExcepcion("No existe session activa.");
				}

				// VERIFICA COLAS

				if (sessionTypeSelected.getCode().equals(SESSION_TYPE_PAUSE)
						|| sessionTypeSelected.getCode().equals(
								SESSION_TYPE_BREAK)
						|| sessionTypeSelected.getCode().equals(
								SESSION_TYPE_BREAK_WITH_CALL)
						|| sessionTypeSelected.getCode().equals(
								SESSION_TYPE_PAUSE_WITH_CALL)
						|| sessionTypeSelected.getCode().equals(
								SESSION_TYPE_LOGOUT_WITH_CALL)
						|| sessionTypeSelected.getCode().equals(
								SESSION_TYPE_PAUSE_WITH_CLOSE)) {
					
					// SE CREA NUEVO ESTADO
					System.out.println("antes de crear el estado");
					Session newState = new Session();
					newState.setAgent(agent);
					newState.setCampaign(campaign);
					newState.setHost(host);
					newState.setPeer(peer);
					newState.setSession(openSession);
					newState.setSessionType(sessionTypeSelected);
					newState.setStartedAt(new Date());
					newState = sessionEao.createSession(newState);
					System.out.println("despues de crear el estado:"+newState.getId());
					sessions.add(newState);

					List<String> queues = queueEao.findQueues(campaign.getId());

					String respuesta = managerBean.pauseManyQueues(queues, peer
							, campaign.getServer().getIp(), campaign
							.getServer().getAmiUser(), campaign.getServer()
							.getAmiPassword(), campaign.getServer().getAmiPort());
					if (!respuesta.equals("OK")) {
						throw new CustomExcepcion(
								"La respuesta del Manager es diferente de OK.");
					}

				} else if (sessionTypeSelected.getCode().equals(
						SESSION_TYPE_READY)) {
					
					// SE CREA NUEVO ESTADO
					Session newState = new Session();
					newState.setAgent(agent);
					newState.setCampaign(campaign);
					newState.setHost(host);
					newState.setPeer(peer);
					newState.setSession(openSession);
					newState.setSessionType(sessionTypeSelected);
					newState.setStartedAt(new Date());
					newState = sessionEao.createSession(newState);
					sessions.add(newState);
					
					List<String> queues = queueEao.findQueues(campaign.getId());

					String respuesta = managerBean.unpauseManyQueues(queues,
							peer, campaign.getServer().getIp(), campaign
									.getServer().getAmiUser(), campaign.getServer()
									.getAmiPassword(), campaign.getServer()
									.getAmiPort());
					if (!respuesta.equals("OK")) {
						throw new CustomExcepcion(
								"La respuesta del Manager es diferente de OK.");
					}
				}else if (sessionTypeSelected.getCode().equals(
						SESSION_TYPE_LOGOUT)) {
					// VERIFICA SESIONES ABIERTAS
					/*Session openSession = sessionEao.findOpenSession(
							campaign.getId(), agentId, sessionTypeSession.getId());*/
						// SE CIERRA LA SESSION
						openSession.setEndedAt(new Date());
						sessionEao.createSession(openSession);

					// VERIFICA COLAS

					List<String> queues = queueEao.findQueues(campaign.getId());

					String respuesta = managerBean.removeManyQueues(queues, peer
							, campaign.getServer().getIp(), campaign.getServer()
							.getAmiUser(), campaign.getServer().getAmiPassword(), campaign
							.getServer().getAmiPort());
					if (!respuesta.equals("OK")) {
						throw new CustomExcepcion(
								"La respuesta del Manager es diferente de OK.");
					}
				}
			}

			AgentDto agentDto = conv.fromAgent(agent);
			List<SessionDto> sessionsDto = new ArrayList<SessionDto>();
			
			for (Session session : sessions) {
			SessionDto sessionDto = conv.fromSession(session);
			sessionsDto.add(sessionDto);
			}
			
			agentDto.setSessions(sessionsDto);
			PeerDto peerDto = new PeerDto();
			peerDto.setName(peer);
			agentDto.setPeer(peerDto);
			
			return agentDto;

		} catch (Exception e) {
			throw new CustomExcepcion(e.getMessage());
		}
	}
	

	

}
